package com.example.lj.uav.utils;

import android.util.Log;

import com.example.lj.uav.bean.PointAction;
import com.example.lj.uav.bean.RouteLine;
import com.example.lj.uav.bean.RoutePoint;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

public class KmlUtils {

    public static boolean addSampleSuccess = false;
    private static String routeType;
    private static RouteLine routeLine = new RouteLine();
    private static List<RoutePoint> points = new ArrayList<>();
    private static String routeName;

    public static void createKml(String filePath, RouteLine line, List<RoutePoint> points) {

        Element root = DocumentHelper.createElement("kml");  //根节点是kml
        Document document = DocumentHelper.createDocument(root);
        document.setXMLEncoding("UTF-8");
        //给根节点kml添加属性
        root.addNamespace("", "http://www.opengis.net/kml/2.2");

        Element documentElement = root.addElement("Document");
        documentElement.addElement("name").addText(line.getFileName());
        Element extendedDataElement = documentElement.addElement("ExtendedData");
        extendedDataElement.addNamespace("mis","www.dji.com");
        extendedDataElement.addElement("mis:type").addText(line.getType());

        Element folderElement = documentElement.addElement("Folder");
        folderElement.addElement("name").addText("Waypoints");
        folderElement.addElement("description").addText("Waypoints in the Mission.");
        StringBuilder builder = new StringBuilder();
        for (int i=0;i<points.size();i++){
            RoutePoint point = points.get(i);
            Element placeMarker = folderElement.addElement("Placemark");

            placeMarker.addElement("name").addText("Waypoint"+(i+1));
            placeMarker.addElement("visibility").addText("1");
            placeMarker.addElement("description").addText("Waypoint");
//            placeMarker.addElement("styleUrl").addText("#waypointStyle");
            Element extenedeData = placeMarker.addElement("ExtendedData").addNamespace("mis","www.dji.com");
            extenedeData.addElement("mis:useWaylineAltitude").addText(point.getUseWaylineAltitude());
            extenedeData.addElement("mis:heading").addText(point.getAngle()+"");
            extenedeData.addElement("mis:turnMode").addText(point.getDirection());
            extenedeData.addElement("mis:gimbalPitch").addText(point.getPitchAngle()+"");
            List<PointAction> actions = point.getActions();
            for (int j=0;j<actions.size();j++){
                Element action = extenedeData.addElement("mis:actions");
                String param = actions.get(j).getParam();
                if (!"".equals(param)) {
                    action.addAttribute("param",param);
                }
                action.addText(actions.get(j).getName());

            }
            Element pointElement = placeMarker.addElement("Point");
            pointElement.addElement("altitudeMode").addText("relativeToGround");
            pointElement.addElement("coordinates").addText(point.getLongitude()+","+point.getLatitude()+","+point.getAltitude());

            if (builder.length()==0){
                builder.append(point.getLongitude()+","+point.getLatitude()+","+point.getAltitude());
            }else{
                builder.append(" "+point.getLongitude()+","+point.getLatitude()+","+point.getAltitude());
            }
        }
        Element placeMarker = documentElement.addElement("Placemark");
        placeMarker.addElement("name").addText("Wayline");
        placeMarker.addElement("visibility").addText("1");
        placeMarker.addElement("description").addText("Wayline");
        placeMarker.addElement("styleUrl").addText("#waypointStyle");
        Element extenedeData = placeMarker.addElement("ExtendedData").addNamespace("mis","www.dji.com");
        extenedeData.addElement("mis:altitude").addText(line.getAltitude()+"");
        extenedeData.addElement("mis:autoFlightSpeed").addText(line.getSpeed()+"");
        extenedeData.addElement("mis:actionOnFinish").addText(line.getActionOnFinish());
        extenedeData.addElement("mis:headingMode").addText(line.getHeadingMode());
        extenedeData.addElement("mis:gimbalPitchMode").addText(line.getGimbalPitchMode());
//        placeMarker.addElement("styleUrl").addText("#waylineGreenPoly");
        Element lineString = placeMarker.addElement("LineString");
        lineString.addElement("tessellate").addText("1");
        lineString.addElement("altitudeMode").addText("relativeToGround");
        lineString.addElement("coordinates").addText(builder.toString());


        try {
            Writer fileWriter = new FileWriter(filePath+"/"+line.getFileName()+".kml");
            //换行
            OutputFormat format = new OutputFormat();
            format.setEncoding("UTF-8");
            format.setNewlines(true);
            // 生成缩进
            format.setIndent(true);
            //dom4j提供了专门写入文件的对象XMLWriter
            XMLWriter xmlWriter = new XMLWriter(fileWriter, format);
            xmlWriter.write(document);
            xmlWriter.flush();
            xmlWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static RouteLine readKmlForLine(){
        return routeLine;
    }

    public static List<RoutePoint> readKmlForPoint(){
        return points;
    }

    public static String getRouteType(String pathName) throws Exception {
        File file = new File(pathName);//pathName为KML文件的路径
        FileInputStream fileInputStream = new FileInputStream(file);
        parseXmlWithDom4j(fileInputStream);
        SAXReader reader = new SAXReader();
        Document document = null;
        document = reader.read(fileInputStream);
        Element root = document.getRootElement();

        List<Element> elements = root.elements();
        Element documentElement = elements.get(0);
        List<Element> documentChildren = documentElement.elements();
        for (int i=0;i<documentChildren.size();i++){
            String name = documentChildren.get(i).getName();
            if ("ExtendedData".equals(name)){
                Element typeElement = documentChildren.get(i).elements().get(0);
                routeType=typeElement.getText();
                Log.e("info",routeType);
            }
        }
        return routeType;
    }

    public static void parseKml(String pathName) throws Exception {
        File file = new File(pathName);//pathName为KML文件的路径
        FileInputStream fileInputStream = new FileInputStream(file);
        parseXmlWithDom4j(fileInputStream);
    }

    public static Boolean parseXmlWithDom4j(InputStream input) throws Exception{
        SAXReader reader = new SAXReader();
        Document document = null;
        try {
            document = reader.read(input);
            Element root = document.getRootElement();//获取doc.kml文件的根结点

            initData(root);
            addSampleSuccess = true;
            //选择sd卡中的kml文件，解析成功后即调用MainActivity中的添加marker的方法向地图上添加样点marker
        } catch (DocumentException e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return addSampleSuccess;
    }

    private static void initData(Element root) {
        List<Element> elements = root.elements();
        Element document = elements.get(0);
        List<Element> documentChildren = document.elements();
        for (int i=0;i<documentChildren.size();i++){
            String name = documentChildren.get(i).getName();
            if ("name".equals(name)){
                routeName = documentChildren.get(i).getName()+"import";
                routeLine.setFileName(routeName);
            }
            if ("ExtendedData".equals(name)){
                Element typeElement = documentChildren.get(i).elements().get(0);
                routeType=typeElement.getText();
                Log.e("info",routeType);
            }
            if ("Waypoint".endsWith(routeType)){//解析航点飞行
                if ("Folder".equals(name)){
                    Element folderElement = documentChildren.get(i);
                    parsePoints(folderElement);
                }
                if ("Placemark".equals(name)){
                    Element routeElement = documentChildren.get(i);
                    parseRoute(routeElement);
                }
            }else{//解析建图航拍
                if ("Placemark".equals(name)){
                    Element routeElement = documentChildren.get(i);
                    parseArea(routeElement);
                }
            }
        }
    }

    private static void parseArea(Element routeElement) {

    }

    private static void parseRoute(Element routeElement) {
        List<Element> placeMarkChildren = routeElement.elements();
        for (int i=0;i<placeMarkChildren.size();i++){
            Element data = placeMarkChildren.get(i);
            if ("ExtendedData".equals(data.getName())){
                List<Element> datas = data.elements();
                for (int j=0;j<datas.size();j++){
                    Element attr = datas.get(j);
                    if ("altitude".equals(attr.getName())){
                        routeLine.setAltitude(Double.parseDouble(attr.getText()));
                    }
                    if ("autoFlightSpeed".equals(attr.getName())){
                        routeLine.setSpeed(Double.parseDouble(attr.getText()));
                    }
                    if ("actionOnFinish".equals(attr.getName())){
                        routeLine.setActionOnFinish(attr.getText());
                    }
                    if ("headingMode".equals(attr.getName())){
                        routeLine.setHeadingMode(attr.getText());
                    }
                    if ("gimbalPitchMode".equals(attr.getName())){
                        routeLine.setGimbalPitchMode(attr.getText());
                    }
                }
            }
        }
    }

    private static void parsePoints(Element folderElement) {
        List<Element> folderChildren = folderElement.elements();
        for (int i=0;i<folderChildren.size();i++){
            String name = folderChildren.get(i).getName();
            if ("Placemark".equals(name)){
                RoutePoint point = new RoutePoint();
                point.setId(i);
                List<Element> placeMarkChildren = folderChildren.get(i).elements();
                for (int j=0;j<placeMarkChildren.size();j++){

                    String name1 = placeMarkChildren.get(j).getName();
                    if ("ExtendedData".equals(name1)){
                        List<Element> datas = placeMarkChildren.get(j).elements();
                        List<PointAction> actions = new ArrayList<>();
                        for (int k=0;k<datas.size();k++){
                            Element element = datas.get(k);
                            if ("useWaylineAltitude".equals(element.getName())){
                                point.setUseWaylineAltitude(element.getText());
                            }
                            if ("heading".equals(element.getName())){
                                point.setAngle(Double.parseDouble(element.getText()));
                            }
                            if ("turnMode".equals(element.getName())){
                                point.setDirection(element.getText());
                            }
                            if ("gimbalPitch".equals(element.getName())){
                                point.setPitchAngle(Double.parseDouble(element.getText()));
                            }
                            if ("actions".equals(element.getName())){
                                PointAction action = new PointAction();
                                action.setId(k);
                                action.setName(element.getText());
                                action.setParam(element.attributeValue("param"));
                                actions.add(action);
                                point.setActions(actions);
                            }

                        }
                    }
                    if ("Point".equals(name1)){
                        List<Element> pointDatas = placeMarkChildren.get(j).elements();
                        for (int l=0;l<pointDatas.size();l++){
                            Element element = pointDatas.get(l);
                            if ("coordinates".equals(element.getName())){
                                String[] s = element.getText().split(",");
                                point.setLongitude(Double.parseDouble(s[0]));
                                point.setLatitude(Double.parseDouble(s[1]));
                                point.setAltitude(Double.parseDouble(s[2]));
                            }
                        }
                    }
                }
                points.add(point);
            }
        }
    }

}
